import { zodResolver } from '@hookform/resolvers/zod' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect } from 'react' import { useForm } from 'react-hook-form' import { toast } from 'sonner' import { Button, Card, CardContent, CardFooter, Form, FormControl, FormField, Switch } from 'ui' import { Admonition, GenericSkeletonLoader } from 'ui-patterns' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { PageContainer } from 'ui-patterns/PageContainer' import { PageHeader, PageHeaderAside, PageHeaderBreadcrumb, PageHeaderDescription, PageHeaderMeta, PageHeaderSummary, PageHeaderTitle, } from 'ui-patterns/PageHeader' import { PageSection, PageSectionContent, PageSectionMeta, PageSectionSummary, PageSectionTitle, } from 'ui-patterns/PageSection' import { BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from 'ui/src/components/shadcn/ui/breadcrumb' import * as z from 'zod' import { TEMPLATES_SCHEMAS } from '@/components/interfaces/Auth/EmailTemplates/AuthTemplatesValidation' import { slugifyTitle } from '@/components/interfaces/Auth/EmailTemplates/EmailTemplates.utils' import { TemplateEditor } from '@/components/interfaces/Auth/EmailTemplates/TemplateEditor' import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import { DocsButton } from '@/components/ui/DocsButton' import { NoPermission } from '@/components/ui/NoPermission' import { useAuthConfigQuery } from '@/data/auth/auth-config-query' import { useAuthConfigUpdateMutation } from '@/data/auth/auth-config-update-mutation' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { DOCS_URL } from '@/lib/constants' import type { NextPageWithLayout } from '@/types' const TemplatePage: NextPageWithLayout = () => { return } const RedirectToTemplates = () => { const router = useRouter() const { templateId, ref } = router.query const { ref: projectRef } = useParams() const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions( PermissionAction.READ, 'custom_config_gotrue' ) const { can: canUpdateConfig } = useAsyncCheckPermissions( PermissionAction.UPDATE, 'custom_config_gotrue' ) const { data: authConfig, isPending: isLoadingConfig } = useAuthConfigQuery({ projectRef }) const { mutate: updateAuthConfig, isPending: isUpdatingConfig } = useAuthConfigUpdateMutation({ onError: (error) => { toast.error(`Failed to update settings: ${error?.message}`) }, onSuccess: () => { toast.success('Successfully updated settings') }, }) // Find template whose slug matches the URL slug const template = templateId && typeof templateId === 'string' ? TEMPLATES_SCHEMAS.find((template) => slugifyTitle(template.title) === templateId) : null // Convert templateId slug to one lowercase word to match docs anchor tag const templateIdForDocs = typeof templateId === 'string' ? templateId.replace(/-/g, '').toLowerCase() : '' // Determine if this is a security notification template const isSecurityTemplate = template?.misc?.emailTemplateType === 'security' // Get the enabled key for security templates const templateEnabledKey = isSecurityTemplate ? (`MAILER_NOTIFICATIONS_${template.id?.replace('_NOTIFICATION', '')}_ENABLED` as string) : null const showConfigurationSection = isSecurityTemplate && templateEnabledKey // Create form schema for security templates const TemplateFormSchema = templateEnabledKey ? z.object({ [templateEnabledKey]: z.boolean(), }) : z.object({}) const defaultValues = templateEnabledKey ? { [templateEnabledKey]: authConfig ? Boolean(authConfig[templateEnabledKey as keyof typeof authConfig]) : false, } : {} const templateForm = useForm>({ resolver: zodResolver(TemplateFormSchema as any), defaultValues, }) const onSubmit = (values: z.infer) => { if (!projectRef) return console.error('Project ref is required') updateAuthConfig({ projectRef: projectRef, config: { ...values }, skipInvalidation: true }) } useEffect(() => { if (authConfig && templateEnabledKey) { templateForm.reset({ [templateEnabledKey]: Boolean(authConfig[templateEnabledKey as keyof typeof authConfig]), }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [authConfig, templateEnabledKey]) if (isPermissionsLoaded && !canReadAuthSettings) { return } if (!templateId) { return null } // Show error if templateId is invalid or template is not found if (!template) { return (
) } return ( <> Emails {template.title} {template.title} {template.purpose || 'Configure and customize email templates.'} {!isPermissionsLoaded || isLoadingConfig ? ( ) : ( <> {showConfigurationSection && ( Configuration
} render={({ field }) => ( )} /> {templateForm.formState.isDirty && ( )}
)} {showConfigurationSection && ( Content )} )}
) } TemplatePage.getLayout = (page) => ( {page} ) export default TemplatePage